/**
 * @file cmd.go
 * @name 命令行
 * @desc 实现类似 pip 的命令行交互
 * @version 0.1
 */

package cmd

import (
	"flag"
	"fmt"
	"nest/internal/pkgerrors"
	"nest/internal/pkgman"
	"os"
	"path/filepath"
	"strings"
)

// 命令管理器
type CommandManager struct {
	// 实际实现中会包含依赖解析器、下载器等
	manager *pkgman.PackageManager
}

// 初始化命令管理器
func NewCommandManager() *CommandManager {
	homedir, err := os.UserHomeDir()
	if err != nil {
		fmt.Println("获取用户主目录失败:", err)
		os.Exit(1)
	}
	// 配置文件路径
	configPath := filepath.Join(homedir, ".nest", "config.json")
	// 初始化包管理器
	manager, err := pkgman.NewPackageManager(configPath)
	if err != nil {
		fmt.Println("初始化元数据管理器失败:", err)
		// return err
	}
	// defer manager.Close()
	return &CommandManager{manager: manager}
}

// 执行
func (cm *CommandManager) Run() error {

	// 确保参数格式正确
	if len(os.Args) < 2 {
		printUsage()
		// return fmt.Errorf("缺少命令参数")
		os.Exit(1)
	}

	// 第一个参数必须是"nest"
	if os.Args[1] != "nest" && !isNestCommand() {
		fmt.Println("错误: 命令必须以'nest'开头    Error: command must start with 'nest'")
		printUsage()
		os.Exit(1)
	}

	/*
		错误处理模式：
		flag.ContinueOnError - 解析出错时返回错误
		flag.ExitOnError - 解析出错时调用 os.Exit(2)（默认行为）
		flag.PanicOnError - 解析出错时 panic
	*/

	// 创建命令行解析器

	/* nestCmd := flag.NewFlagSet("nest", flag.ExitOnError)
	nestCmd.String("pkg", "", "包名(必填)") */

	//====== start 打包 命令 ======
	/* packCmd := flag.NewFlagSet("pack", flag.ExitOnError)
	packPkg := packCmd.String("pkg", "", "包名(可选)")
	packVer := packCmd.String("version", "", "版本 (可选)") */
	//====== end 打包 命令 ======

	//====== end 安装 命令 ======
	installCmd := flag.NewFlagSet("install", flag.ExitOnError)
	//名称，默认值，提示
	installPkg := installCmd.String("pkg", "", "包名(必填)")
	installVer := installCmd.String("version", "", "版本 (可选)")
	//====== end 安装 命令 ======

	//====== start 卸载包 命令 ======
	uninstallCmd := flag.NewFlagSet("uninstall", flag.ExitOnError)
	uninstallPkg := uninstallCmd.String("pkg", "", "包名(必填)")
	uninstallVer := uninstallCmd.String("version", "", "版本 (可选)")
	//====== end 卸载包 命令 ======

	//====== start 查看 命令 ======
	listCmd := flag.NewFlagSet("list", flag.ExitOnError)
	//====== end 查看 命令 ======

	//====== start 搜索 命令 ======
	searchCmd := flag.NewFlagSet("list", flag.ExitOnError)
	//====== end 搜索 命令 ======

	//====== start 缓存 命令 ======
	/* cacheCmd := flag.NewFlagSet("cache", flag.ExitOnError)
	purgePkg := cacheCmd.String("purge", "", "清除所有缓存 (可选)") */
	/* removePkg := cacheCmd.String("remove", "", "删除指定缓存 (可选)")
	packageNamePkg := cacheCmd.String("pkg", "", "包名 (可选)") */
	//====== end 缓存 命令 ======
	switch os.Args[1] {
	case "init":
		if err := cm.InitPackage(); err != nil {
			return err
		}
		return nil
	case "login":
		pkgerrors.PrintInfo("nest 提示：请在 http://local.nest.cn 登录")
		pkgerrors.PrintInfo("登录：http://local.nest.cn/session/17638ebb-a59f-4d9c-9c7d-82b26aa8fae0")
		pkgerrors.PrintInfo("按回车在浏览器中打开")
		if err := cm.Login(); err != nil {
			return err
		}
		// return pkgerrors.WrapSuccess(pkgerrors.LevelInfo, pkgerrors.Success, "打包成功")
		return nil
	case "publish":
		if err := cm.PublishPackage(); err != nil {
			return err
		}
		return nil
	case "install":

		installCmd.Parse(os.Args[2:])
		/**
		 * 位置参数处理：
		 * 1. 如果没有指定 -pkg 参数，则从位置参数中获取包名和版本
		 * 2. 如果指定了 -pkg 参数，则从位置参数中获取版本
		 * 例1：nest install express 1.0.0
		 * 例2：nest install express
		 */
		if *installPkg == "" && installCmd.NArg() > 0 {
			*installPkg = installCmd.Arg(0)
			if installCmd.NArg() > 1 {
				*installVer = installCmd.Arg(1)
			}
		}
		/**
		 * 标记参数处理：
		 * 1. 如果没有指定 -pkg 参数，则从位置参数中获取包名和版本
		 * 2. 如果指定了 -pkg 参数，则从位置参数中获取版本
		 * 例1：nest install -pkg=express -version=1.0.0
		 */
		if *installPkg == "" {
			installCmd.Usage = func() {
				fmt.Println("安装用法: nest install [-pkg=包名] [-version=版本]")
				fmt.Println("或")
				fmt.Println("安装用法: nest install 包名 [版本]")
				installCmd.PrintDefaults()
			}
			installCmd.Usage()
			os.Exit(1)
		}
		version := *installVer
		if version == "" {
			version = "*" // 最新版本
		}
		if err := cm.InstallPackage(*installPkg, version); err != nil {
			return err
		}
		return nil
	case "uninstall":
		uninstallCmd.Parse(os.Args[2:])
		if *uninstallPkg == "" && uninstallCmd.NArg() > 0 {
			*uninstallPkg = uninstallCmd.Arg(0)
			if uninstallCmd.NArg() > 1 {
				*uninstallVer = uninstallCmd.Arg(1)
			}
		}
		if *uninstallPkg == "" {
			uninstallCmd.Usage()
			os.Exit(1)
		}
		if err := cm.Uninstall(*uninstallPkg, *uninstallVer); err != nil {
			// 卸载失败
			return err
		}

		return nil
	case "list":
		listCmd.Parse(os.Args[2:])
		if err := cm.List(); err != nil {
			fmt.Printf("列出包失败: %v\n", err)
			os.Exit(1)
		}
	case "search":
		searchCmd.Parse(os.Args[2:])
		if err := cm.List(); err != nil {
			fmt.Printf("搜索包失败: %v\n", err)
			os.Exit(1)
		}
	case "cache":
		/* // 处理缓存命令
		cacheCmd.Parse(os.Args[2:])
		if *purgePkg == "" && cacheCmd.NArg() > 0 {
			*purgePkg = cacheCmd.Arg(0)
			if cacheCmd.NArg() > 1 {
				*packVer = cacheCmd.Arg(1)
			}
		}
		if err := cm.ClearCache(*purgePkg, *packVer); err != nil {
			return err
		} */
		return nil

	case "version", "-v", "--version":
		pkgerrors.PrintInfo("1.0.0")
		os.Exit(1)
	case "help", "-h", "--help":
		displayHelp("帮助:")
		os.Exit(1)
	default:
		pkgerrors.PrintError("未知命令: ", os.Args[0])
		// displayHelp("可用命令:")
		os.Exit(1)
	}
	return nil
}
func isNestCommand() bool {
	// 检查程序名是否包含"nest"（考虑不同执行方式）
	nestName := strings.Contains(os.Args[0], "nest")
	if !nestName {
		return false
	}
	return true
}
func displayHelp(desc string) {
	pkgerrors.PrintInfo(desc)
	pkgerrors.PrintInfo("	install   <package>  - 安装包")
	pkgerrors.PrintInfo("	update    <package>  - 更新所有包或指定包")
	pkgerrors.PrintInfo("	uninstall <package>  - 卸载包")
	pkgerrors.PrintInfo("	list      <query>    - 查看包")
	pkgerrors.PrintInfo("")
}
func printUsage() {
	fmt.Println(`Usage: nest <command> [arguments]

Commands:
  install <package>  Install a package
  help               Show this help message

Examples:
  nest install ss
  nest install ss --version 1.0.0`)
}

func printInstallUsage() {
	fmt.Println(`Usage: nest install <package> [options]

Options:
  --version string  Specify package version
  --force           Force installation

Example:
  nest install ss --version 1.2.0`)
}
